package com.tinyengine.it.tool;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Slf4j
public class ZipUtils {

    /**
     * 递归压缩文件夹及其内容
     *
     * @param folder
     * @param parentFolderName
     * @param zipOut
     * @throws IOException
     */
    public static void zipDirectory(Path folder, String parentFolderName, ZipOutputStream zipOut) throws IOException {
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(folder)) {
            boolean isEmptyDirectory = true;  // 用于标记当前文件夹是否为空

            for (Path entry : stream) {
                isEmptyDirectory = false; // 遇到文件或文件夹时，标记为非空文件夹
                if (Files.isDirectory(entry)) {
                    // 递归处理子目录，注意这里我们传递的是子目录的名称，而不是整个父目录路径
                    zipDirectory(entry, parentFolderName + FileUtil.FILE_SEPARATOR + entry.getFileName().toString(), zipOut);
                } else {
                    // 压缩文件
                    zipOut.putNextEntry(new ZipEntry(parentFolderName + FileUtil.FILE_SEPARATOR + entry.getFileName()));
                    Files.copy(entry, zipOut);
                    zipOut.closeEntry();
                }
            }
            // 如果是空文件夹，添加空文件夹的条目
            if (isEmptyDirectory) {
                zipOut.putNextEntry(new ZipEntry(parentFolderName + FileUtil.FILE_SEPARATOR));
                zipOut.closeEntry();
            }
        }
    }

    public static void unzip(InputStream zipFileStream, String targetDirectory) throws IOException {
        // 创建一个 ZipInputStream 对象
        try (ZipInputStream zipInputStream = new ZipInputStream(zipFileStream)) {
            ZipEntry entry;

            // 逐个读取 ZIP 文件中的条目
            while ((entry = zipInputStream.getNextEntry()) != null) {
                File targetFile = new File(targetDirectory, entry.getName());

                // 如果是目录，则创建目录
                if (entry.isDirectory()) {
                    if (!targetFile.exists()) {
                        targetFile.mkdirs();
                    }
                } else {
                    // 如果是文件，则解压文件
                    if (!FileUtil.exist(targetFile)) {
                        FileUtil.touch(targetFile);
                    }
                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile))) {
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = zipInputStream.read(buffer)) > 0) {
                            bos.write(buffer, 0, length);
                        }
                    }
                }
                zipInputStream.closeEntry();
            }
        }
    }

    public static void deleteAllFilesInDir(String dirPath) {
        File dir = Paths.get(dirPath).toFile();

        if (dir.exists() && dir.isDirectory()) {
            // 获取目录下的所有文件和子目录
            File[] files = dir.listFiles();

            if (files != null) {
                for (File file : files) {
                    // 删除每一个文件或子目录
                    try {
                        FileUtil.del(file);
                    } catch (IORuntimeException e) {
                        log.error("文件不存在:{}", file.getAbsolutePath());
                    }
                }
            }
        }
    }
}
